﻿/*
   Advanced Flash Engine in ActionScript 3.
   Copyright (C) 2009  Dean Gardiner, Taylor Lodge

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.winmastergames.lolgame {
	/* =============Class Imports============= */
	import flash.display.MovieClip;
	import com.winmastergames.lolgame.weapons.*;
	import flash.events.*;
	import flash.geom.Point;
	import flash.text.TextField;
	import flash.geom.Rectangle;
	import com.senocular.utils.KeyObject;
	import com.winmastergames.lolgame.gameUtils;
	import com.adventuresinactionscript.collisions.HitTest;
	import flash.display.*;
	import com.winmastergames.lolgame.engine;
	import flash.ui.Keyboard;
	import flash.utils.Timer;
	import flash.ui.Mouse;
	import com.winmastergames.gameassets.xperience;
	import com.winmastergames.lolgame.turret;
	
	public class player extends MovieClip {
		//Current Weapons in game not sure if we need this
		//Variables relating to weapons
		//Array for holding weapons you currently have
		private var weapons:Array = new Array("Deagle", "Berreta", "M1911", "USP", "MP5", "P90", "Mini-Uzi", "Ump", "Spas-12", "M3", "XM1014", "AA12", "Pancor Jackhammer", "M4A1", "Ak-47", "G36C", "G3", "M249", "G36K", "M60", "MiniMe", "Gau-8", "RPD");
		public static var currentWeaponArray:Array = new Array;
		//Current weapon slot your using
		public static var currentWeapon:Number;
		//How much damage your gun does
		public var weaponDamage:Number;
		//Variable for temporarly holding the weapon damage when we do level weapon damage increases
		public var tempWeaponDamage:Number;
		//If your gun is semi automatic or not
		public var semiAutomatic:Boolean;
		//Delay between shots
		public var weaponFireTime:Number;
		//How long it takes to reload your gun
		public var weaponReloadTime:Number;
		//How many bullets in your clip
		public static var weaponClipSize:Number;
		//Type of weapon your holding, LMG,Shotgun,SMG etc
		public static var weaponType:String;
		//Tells game if your allowed to switch weapons
		public var canSwitchWeapon:Boolean = true;
		//Used to disable weapon switching when reloading
		public var canSwitchWeaponAmmo:Boolean;
		//Ammo type of gun, 50Cal,9MM etc
		public static var ammoType:String;
		//If you have enough ammo to reload
		public var canReloadAmmo:Boolean;
		//Stops you from being able to fire during reloads
		public static var canFire:Boolean = true;
		public var updateDamage:Boolean = false;
		public var canSpawnTurret:Boolean = true;
		public var isSpawningTurret:Boolean = false;
		//Ammo variables
		//Ammo count for the different types of ammo
		public static var ammoFiftyC:Number;
		public static var ammoSevenSevenTwo:Number;
		public static var ammoNineMM:Number;
		public static var ammoFiveFiveSix:Number;
		public static var ammoTwelveGauge:Number;
		public static var ammoFiveSeven:Number;
		public static var ammoFortyFive:Number;
		public var updateWeaponTimer:Timer = new Timer(50);
		public var canReload:Boolean = true;
		public var remainingAmmo:Number;
		public static var mouseClicked:Boolean = false;
		//Variables relating to the stage
		public var stageRef:Stage;
		private var keyF:uint = 70; //Uint Code for F
		private var keyR:uint = 82; //Uint Code for R
		private var key:KeyObject; //Captures senoculars keyObject for use
		private var keyQ:uint = 81; //Uint Code for Q
		private var keyB:uint = 66; //Uint Code for B
		var oldx:Number; //Old x pos of gun you pick up
		var oldy:Number; //Old y pos of gun you pick up
		var canPickUpWeapon:Boolean; //Tells the game if your allowed to pick up a new gun
		var oldWeapon:String; //Stores old weapon for when you drop it
		var drop:Number; //Used to determine if you will drop your gun or not
		public var currentWeaponText:String = currentWeaponArray[currentWeapon];
		var Lol:Number = 1; //Hack way of giving you a gun on spawn
		var SessionPickup:Boolean = false;
		public static var st_weaponDamage;
		public static var updateWeapon:Boolean = true;
		public var reloadTimer = new Timer(1);
		public var tempAmmoRemaining:Number;
		public var updateOnce:Boolean = true;
		public var tempAmmo:Number = 0;
		//PowerUp framework
		//Need a death timer and boolen for if on for each powerup
		public static var damagePowerUp:Boolean = false; //This is the boolen for checking if the damage powerup is active
		public var invincibilityPowerUp:Boolean = false;
		public static var instaPowerUp:Boolean = false;
		//It's used so that the weapon damage does not reset
		public var damagePowerUpTimer:Timer = new Timer(15000); //This is the timer for deleting it after 15 seconds
		public var invincibilityPowerUpTimer:Timer = new Timer(15000);
		public var instaPowerUpTimer:Timer = new Timer(15000);
		public static var playerHealth = 100;
		var killed:Boolean = false;
		var keyShift:uint = 16;
		var stamina:Number = 100;
		public static var running:Boolean = false;
		public static var money:Number = 0;
		public static var healthRegen:Timer = new Timer(1500);
		public static var regen:Boolean = false;
		
		//End of PowerUp framework
		/* =============Engine Constructor============= */
		public function player(stageRef:Stage){
			//PowerUp framework
			//Need an event listener for the timer for each powerup so we can tell it what to do at the end of the timer
			damagePowerUpTimer.addEventListener(TimerEvent.TIMER, damagePowerUpEnd); //This one is for the 2x damage timer even it's used for setting the powerupOn to false and reseting the timer
			instaPowerUpTimer.addEventListener(TimerEvent.TIMER, instaPowerUpEnd);
			invincibilityPowerUpTimer.addEventListener(TimerEvent.TIMER, invincibilityPowerUpEnd);
			healthRegen.addEventListener(TimerEvent.TIMER, regenStart);
			//End of PowerUp framework
			addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
			this.stageRef = stageRef;
			onSpawn();
			key = new KeyObject(stageRef);
		} //End Constructor
		
		public function reloadTime(e:Event){
			reloadFunction();
		}
		
		public function reloadFunction()
		{
			canReload = true;
			tempAmmoRemaining = weaponClipSize - engine.ammoRemaining;
			
			for (var w:Number = 0; w <= tempAmmoRemaining; w++){
				switch (ammoType){
					case "9MM":
						if (ammoNineMM > 0){
							//engine.ammoRemaining++;
							tempAmmo = engine.ammoRemaining++;
							currentWeaponArray[currentWeapon].setAmmo(tempAmmo);
							ammoNineMM--;
						}
						break;
				}
			}
			//tempAmmo = engine.ammoRemaining++;
			//currentWeaponArray[currentWeapon].setAmmo(tempAmmo);
			updateWeapon = true;
			reloadTimer.stop();
			reloadTimer.reset();
			canFire = true;
		}
		
		function regenStart(e:Event){
			regen = true;
			healthRegen.stop();
			healthRegen.reset();
		}
		
		//PowerUp framework
		//This is the function that get's run when the powerup timers run out one is needed for each powerup
		function damagePowerUpEnd(e:Event){
			damagePowerUp = false; //Stops the damagePowerUp from being active so you don't the powerups abilitys
			damagePowerUpTimer.stop(); //Stops the timer
			damagePowerUpTimer.reset(); //Resets timer
		}
		
		function invincibilityPowerUpEnd(e:Event){
			engine.god = false;
			invincibilityPowerUp = false;
			invincibilityPowerUpTimer.stop();
			invincibilityPowerUpTimer.reset();
		}
		
		function instaPowerUpEnd(e:Event){
			instaPowerUp = false;
			instaPowerUpTimer.stop();
			instaPowerUpTimer.reset();
		}
		
		//End of PowerUp framework
		public function onSpawn(){
			ammoSevenSevenTwo = 60; //Gives you 60 7.72 rounds on spawn
			ammoTwelveGauge = 24; //Gives you 24 12 Gauge rounds on spawn
			ammoNineMM = 999; //Gives you 120 9MM rounds on spawn
			ammoFiveFiveSix = 90; //Gives you 90 5.56 rounds on spawn
			ammoFiveSeven = 90; //Gives you 90 5.7 rounds on spawn
			ammoFortyFive = 90; //Gives you 90 .45 rounds on soawn
			ammoFiftyC = 60; //GIves you 60 Fifty cal rounds on spawn
			currentWeapon = 0; //Sets current Weapon slot to 0
			canPickUpWeapon = true; //Tells game you can pick up weapons
			gotoAndStop(2);
		}
		
		public function reloadStart()
		{
			canReload = false;
			reloadTimer = new Timer(weaponReloadTime * 1000);
			reloadTimer.addEventListener(TimerEvent.TIMER, reloadTime);
			reloadTimer.start();
			canFire = false;
		}
		
		public function loop(e:Event):void {
			//trace("X: " + engine.st_playerTarget.x + " Y: " + engine.st_playerTarget.y);
			if (playerHealth < 0)
			{
				playerHealth = 0;
			}
			if (key.isDown(keyQ))
			{
				gotoAndStop("walk");
			}
			else
			{
				gotoAndStop("notwalk");
			}
			if (regen == true){
				if (playerHealth < 100){
					playerHealth++;
				} else
					regen = false;
			}
			healthRegen.start();
			
			if (mouseClicked == true){
				if (isSpawningTurret == true){
					isSpawningTurret = false;
					
					for (var p:Number = 0; p < engine.st_turretArray.length; p++){
						if (engine.st_turretArray[p].buying == true){
							engine.st_turretArray[p].killSelf();
							engine.st_turretArray[p] = null;
							engine.st_turretArray.splice(p, 1);
						}
					}
					engine.st_turretArray.push(new turret(engine.st_level_mc, stage.mouseX - engine.st_level_mc.x, stage.mouseY - engine.st_level_mc.y, true, false));
					isSpawningTurret = false;
					canSpawnTurret = true;
				}
				mouseClicked = false;
			}
			
			if (key.isDown(keyB) && canSpawnTurret == true && money >= 100){
				money -= 100;
				canSpawnTurret = false;
				isSpawningTurret = true;
				engine.canFire = false;
				engine.st_turretArray.push(new turret(engine.st_level_mc, stage.mouseX - engine.st_level_mc.x, stage.mouseY - engine.st_level_mc.y, false, true));
			} else if (money < 100 && key.isDown(keyB)){
				trace("Not enough money you need " + (100 - money) + " more money");
			}
			
			if (key.isDown(keyF)){
				/*var tempDist:Number = globals.getDistance(engine.st_playerTarget.x, engine.st_playerTarget.y, engine.barrierHand.barriers[0].b_x, engine.barrierHand.barriers[0].b_y);
				
				if (tempDist <= 40){
					engine.barrierHand.barriers[0].b_damageLevel = 0;
				}*/
			}
			
			if (key.isDown(keyShift) && stamina > 0){
				running = true;
				stamina -= 3;
				
				if (stamina == 0){
					running = false;
				}
			} else if (!key.isDown(keyShift)){
				if (stamina < 100){
					stamina += 2;
				}
				running = false;
			}
			
			//Weapon Pickups
			/*
			 * Loops through all weapons on the ground
			 * If you're allowed to pickup weapons
			 * Checks if you're hit testing them and F is down
			 * Checks how many weapons you have, If 1 pick's up and switchs to it or if 2 picks up and tells the drop to happen
			 * If you had 2 weapons finds out what one you were ment to drop and drops it at your x,y position
			 */
			for (var i:Number = 0; engine.pickupsArrayRO[i]; i++){
				//Hack way of giving you a weapon on spawn.
				if (Lol == 1){
					//Gives you a USP
					currentWeaponArray.push(engine.pickupsArrayRO[0]);
					//Set's Lol to 0 so that you don't get USP spam :)
					Lol = 0;
				}
				
				//If your allowed to pick up weapons continue
				if (canPickUpWeapon == true && SessionPickup == false){
					//If hit testing the gun and F is down continue
					if (hitTestObject(engine.pickupsArrayRO[i]) && key.isDown(keyF)){
						//Sets canPickUpWeapon to false to prevent pickup spam
						canPickUpWeapon = false;
						//Captures weapons x pos in oldx
						oldx = engine.pickupsArrayRO[i].x;
						//Captures weapons y pos in oldy
						oldy = engine.pickupsArrayRO[i].y;
						
						//Checks if currentWeaponArray is longer then 1 meaning you have used both weapon slots, That the current slot is not for melee weapons and that the weapon on the ground is not in either of the weapon slots
						if (currentWeaponArray.length > 1 && currentWeaponArray[0].toString() != engine.pickupsArrayRO[i].toString() && currentWeaponArray[1].toString() != engine.pickupsArrayRO[i].toString()){
							//Captures weapon to drop in oldWeapon
							oldWeapon = currentWeaponArray[currentWeapon];
							//Sets currently held weapon on the ground
							currentWeaponArray[currentWeapon] = engine.pickupsArrayRO[i];
							//Tells game to drop the gun
							drop = 1;
							//Tells the gun's onPickup function to run with an id of of the value of i
							engine.pickupsArrayRO[i].onPickup(i);
							//Tells engine to update the ammo hud
							updateWeapon = true;
						} //Same comments as above
						else if (currentWeaponArray[0].toString() != engine.pickupsArrayRO[i].toString()){
								oldWeapon = currentWeaponArray[currentWeapon];
								currentWeaponArray.push(engine.pickupsArrayRO[i]);
								engine.pickupsArrayRO[i].onPickup(i);
								updateWeapon = true;
								currentWeapon = 1;
						}
						//If drop = 1 run the switch statement to evalute what gun to spawn
						if (drop == 1){
							//Switchs oldweapon which was the prevouisly held weapon
							switch (oldWeapon){
								case "[object USP]": //If oldWeapon was USP
									engine.pickupsArrayRO.push(new USP(engine.st_level_mc, oldx, oldy, engine.ammoRemaining)); //Push a USP into the pickups array at the old weapons oldx,oldy values
									break;
								case "[object Glock]": //If oldWeapon was Glock
									engine.pickupsArrayRO.push(new Glock(engine.st_level_mc, oldx, oldy, engine.ammoRemaining)); //Push a Glock into the pickups array at the old weapons oldx,oldy values
									break;
							}
						}
						engine.pickupsArrayRO.splice(i, 1);
						SessionPickup = true;
						updateDamage = true;
					}
				} else {
					canPickUpWeapon = true; //If none of the above code is running make it so you can pick up weapons.
				}
				
				//PowerUp framework
				//This is where the hittesting/activating powerups happens
				//Loops through all powerups
				for (var l:Number = 0; l < engine.powerupsArrayRO.length; l++){
					if (engine.powerupsArrayRO[l] != 1337){
						if (hitTestObject(engine.powerupsArrayRO[l])){
							//This is the switch statement for switching through the powerups when pickud up
							switch (engine.powerupsArrayRO[l].toString()){
								//To create a new powerup you need to
								//1. copy the current powerup file and rename it to want you want the powerup to be and add it to the powerup array in enemys/enemy.as
								//2. Add the timer,boolen and place the if statement to stop code from running that resets the powerups effect if applys
								//3. Add the powerup here with this case [object powerupname] and set it's boolen to true, start the timer and run the code that the powerup is meant to do
								case "[object damage]":
									damagePowerUp = true; //Sets the damagepowerup to active
									weaponDamage = weaponDamage * 2; //This is the code for the damage powerup it just double your current weapon damage
									damagePowerUpTimer.start(); //Starts the timer for later use.
									break;
								case "[object instakill]":
									instaPowerUp = true;
									weaponDamage = 999999999999999999999999999999999999999;
									instaPowerUpTimer.start();
									break;
								case "[object ammo]":
									engine.ammoRemaining = weaponClipSize;
									break;
								case "[object repair]":
									break;
								case "[object invincibility]":
									invincibilityPowerUp = true;
									engine.god = true;
									invincibilityPowerUpTimer.start();
									break;
							}
							engine.powerupsArrayRO[l].removePowerup(); //Deletes powerup from map
							engine.powerupsArrayRO[l] = 1337; //Set's the powerup to 1337 so we ignore it from now on
						}
					}
				}
				
				//End of PowerUp framework
				if (!key.isDown(keyF)){
					SessionPickup = false;
				}
				
				//Mouse Position Variables
				if (gameUtils.getState() != "pausemenu" && gameUtils.getState() != "console"){
					//Captures mouse x,y values for later use in facing character at the mouse
					var yDistance:Number = stageRef.mouseY - y;
					var xDistance:Number = stageRef.mouseX - x;
					var radian:Number = Math.atan2(yDistance, xDistance); //Figures out angle to point the character in
					rotation = radian * 180 / Math.PI; //Points character at the mouse
				}
				
				//Check if TAB is down and if canSwtichWeapon is true switch weapon
				if (key.isDown(keyQ)){
					if (canSwitchWeapon == true){
						updateDamage = true;
						//Turn canswitch weapon off so it does not loop
						canSwitchWeapon = false;
						
						//Check if current weapon slot is 0 and the next array slot is not null and then change to slot 1 
						if (currentWeapon == 0 && currentWeaponArray[1] != null){
							currentWeapon = 1;
							updateWeapon = true;
						} else {
							//Else if slot is 1 and the next array slot is not null then change to slot 0
							if (currentWeaponArray[0] != null){
								currentWeapon = 0;
								updateWeapon = true;
							}
						}
					}
				} //If TAB is not down make it so you can switch weapons again
				else {
					canSwitchWeapon = true;
				}
				
				switch (ammoType){
					case "9MM":
						if (ammoNineMM > 0){
							canReloadAmmo = true;
						}
						break;
				}
				
				if ((key.isDown(keyR) || engine.ammoRemaining == 0) && canReload == true && canReloadAmmo == true){
					reloadStart();
				}
				canReloadAmmo = false;
				
				//Weapon Switching
				//Switch currentWeaponArray with the currentWeapon value which corresponds to the slot your using
				switch (currentWeaponArray[currentWeapon].toString()){
					//Weapon values
					case "Deagle":
						weaponDamage = 70;
						weaponClipSize = 7;
						weaponReloadTime = 2.5;
						weaponFireTime = 1.2;
						weaponType = "Pistol";
						ammoType = "50cal";
						gotoAndStop("Deagle");
						break;
					case "[object USP]":
						//PowerUp framework
						//This is how to set up a powerup effect
						//The if statement makes sure the normal code is not run when the powerup is active
						if (!damagePowerUp && !instaPowerUp){
							weaponDamage = 50; //Here is the default code
						}
						//End of PowerUp frameworkd
						weaponClipSize = 15;
						weaponReloadTime = 1.9;
						weaponFireTime = 0;
						weaponType = "Pistol";
						ammoType = "9MM";
						semiAutomatic = true;
						gotoAndStop("USP");
						break;
					case "[object Glock]":
						if (!damagePowerUp && !instaPowerUp){
							weaponDamage = 40;
						}
						weaponClipSize = 20;
						weaponReloadTime = 1.6;
						weaponFireTime = 0.8;
						weaponType = "Pistol";
						ammoType = "9MM";
						semiAutomatic = false;
						if (updateOnce == true){
							engine.ammoRemaining = weaponClipSize;
						}
						gotoAndStop("Glock");
						break;
					case "Berreta":
						weaponDamage = 30;
						weaponClipSize = 15;
						weaponReloadTime = 1.7;
						weaponFireTime = 0.6;
						weaponType = "Pistol";
						ammoType = "9MM";
						gotoAndStop("Berreta");
						break;
					case "FiveSeven":
						weaponDamage = 60;
						weaponClipSize = 20;
						weaponReloadTime = 1.3;
						weaponFireTime = 0.5;
						weaponType = "Pistol";
						ammoType = "5.7";
						gotoAndStop("FiveSeven");
					case "M1911":
						weaponDamage = 50;
						weaponClipSize = 15;
						weaponReloadTime = 1.5;
						weaponFireTime = 0.7;
						weaponType = "Pistol";
						ammoType = ".45";
						gotoAndStop("M1911");
						break;
					case "MP5":
						weaponDamage = 30;
						weaponClipSize = 30;
						weaponReloadTime = 3;
						weaponFireTime = 0.5;
						weaponType = "SMG";
						ammoType = "9MM";
						gotoAndStop("MP5");
						break;
					case "P90":
						weaponDamage = 20;
						weaponClipSize = 50;
						weaponReloadTime = 2;
						weaponFireTime = 0.4;
						weaponType = "SMG";
						ammoType = "5.7";
						gotoAndStop("USP");
					case "Spas-12":
						weaponDamage = 10;
						weaponClipSize = 12;
						weaponReloadTime = 1;
						weaponFireTime = 1;
						weaponType = "Shotgun";
						gotoAndStop("Spas-12");
						break;
					case "M4A1":
						weaponDamage = 30;
						weaponClipSize = 30;
						weaponReloadTime = 3;
						weaponFireTime = 0.5;
						weaponType = "Rifle";
						gotoAndStop("M4A1");
						break;
					default: //Default weapon only able to get through extreme 1337ness
						weaponDamage = 999;
						weaponClipSize = 999;
						weaponReloadTime = 0.1;
						weaponFireTime = 0.1;
						weaponType = "null";
						semiAutomatic = false;
						gotoAndStop("God");
						break;
				}
				updateOnce = false;
				
				if (updateDamage){
					for (var o:Number = 0; o <= xperience.level; o++){
						weaponDamage = weaponDamage + (weaponDamage * 8 / 100);
					}
					/*trace(8 * xperience.level);
					 trace(8 / 40 * 100);*/
					updateDamage = false;
				}
			}
		}
	}
}